﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Security.Cryptography;

namespace ExpLib.SSO
{
    public class SignHelper:IDisposable
    {
        RSACryptoServiceProvider m_CryptoService = null;
        HashAlgorithm m_HashAlgorithm = null;
        Encoding m_Encoding = null;


        SSOServerSection section = System.Configuration.ConfigurationManager.GetSection("SSOSection") as SSOServerSection;

        #region 构造方法
        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="cryptoService">用于签名和验签的RSA加密实现</param>
        /// <param name="hashAlgorithm">用于签名和验签的Hash算法</param>
        /// <param name="encoding">编码方式</param>
        public SignHelper(RSACryptoServiceProvider cryptoService, HashAlgorithm hashAlgorithm, Encoding encoding)
        {
            m_CryptoService = cryptoService;
            m_HashAlgorithm = hashAlgorithm;
            m_Encoding = encoding;
        }

        /// <summary>
        /// 使用默认的参数构造实例  哈希算法用SHA512，编码方法用Utf-8
        /// </summary>
        public SignHelper()
        {
            m_CryptoService = new RSACryptoServiceProvider(512);
            m_HashAlgorithm = new SHA1CryptoServiceProvider();
            
            m_Encoding = System.Text.UTF8Encoding.UTF8;
        }


        /// <summary>
        /// 构造方法，指定哈稀算法和编码方式
        /// </summary>
        public SignHelper(HashAlgorithm hashAlgorithm, Encoding encoding)
        {
            m_CryptoService = new RSACryptoServiceProvider(512);
            m_Encoding = System.Text.UTF8Encoding.UTF8;
        }
        /// <summary>
        /// 构造方法，指定编码方式，其它的用默认方法
        /// </summary>
        public SignHelper(Encoding encoding)
        {
            m_CryptoService = new RSACryptoServiceProvider(512);
            m_HashAlgorithm = new SHA1CryptoServiceProvider();

        }
        /// <summary>
        /// 构造方法，指定哈希算法，其它的用默认方法
        /// </summary>
        public SignHelper(HashAlgorithm hashAlgorithm)
        {
            m_CryptoService = new RSACryptoServiceProvider(512);
            m_Encoding = System.Text.UTF8Encoding.UTF8;

        }
        #endregion

        /// <summary>
        /// 导入公钥或私钥
        /// </summary>
        /// <param name="xmlString"></param>
        public void FromXmlString(String xmlString)
        {
            m_CryptoService.FromXmlString(xmlString);
        }


        //// <summary>
        /// 签名用户信息
        /// </summary>
        /// <param name="data">要签名的数据</param>
        /// <returns></returns>
        public String SignatueData(String data)
        {

            byte[] dataToSignatue = m_Encoding.GetBytes(data);
            var rest = m_CryptoService.SignData(dataToSignatue, m_HashAlgorithm);
            return Convert.ToBase64String(rest);
        }

        /// <summary>
        /// 验证用户的签名
        /// </summary>
        /// <param name="data">要验证的原始数据</param>
        /// <param name="signedData">签名的数据</param>
        /// <returns>验证的结果</returns>
        public bool ValidataData(String data, String signedData)
        {

            return m_CryptoService.VerifyData(m_Encoding.GetBytes(data),m_HashAlgorithm,Convert.FromBase64String(signedData));
        }

        /// <summary>
        /// 验证用户的签名,不抛出异常
        /// </summary>
        /// <param name="data">要验证的原始数据</param>
        /// <param name="signedData">签名的数据</param>
        /// <param name="throwEx">验证失败时的异常信息</param>
        /// <returns>验证结果</returns>
        public bool TryValidataData(String data, String signedData, Exception throwEx = null)
        {
            try
            {
                return m_CryptoService.VerifyData(m_Encoding.GetBytes(data), m_HashAlgorithm, Convert.FromBase64String(signedData));
            }
            catch (Exception ex)
            {
                throwEx = ex;
                return false;
            }
        }

        public void Dispose()
        {
            if (m_HashAlgorithm != null)
                m_HashAlgorithm.Dispose();

            if (m_CryptoService != null)
                m_CryptoService.Dispose();
        }
    }
}
